package com.yycx.module.bus.provider.service.impl;

import com.yycx.common.constants.CommonConstants;
import com.yycx.common.mybatis.base.service.impl.BaseServiceImpl;
import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.mybatis.model.ResultBody;
import com.yycx.common.mybatis.query.CriteriaQuery;
import com.yycx.common.mybatis.query.CriteriaSave;
import com.yycx.common.mybatis.query.CriteriaUpdate;
import com.yycx.common.utils.ApiAssert;
import com.yycx.common.utils.DateUtils;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.module.bus.client.entity.*;
import com.yycx.module.bus.provider.mapper.BusSupplierRateMapper;
import com.yycx.module.bus.provider.service.BusOrderDetailsService;
import com.yycx.module.bus.provider.service.BusSupplierRateService;
import com.yycx.module.bus.provider.service.BusDrugsService;
import com.yycx.module.system.client.entity.SysFormula;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 药品配置接口实现类
 *
 * @author flyme
 * @date 2020-08-02
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BusSupplierRateServiceImpl extends BaseServiceImpl<BusSupplierRateMapper, BusSupplierRate> implements BusSupplierRateService {


    @Autowired
    private BusDrugsService drugsService;

    @Autowired
    private BusOrderDetailsService orderDetailsService;

    @Override
    public ResultBody beforeAdd(CriteriaSave cs, BusSupplierRate bdc, EntityMap extra) {
        bdc.setConfigState(CommonConstants.ENABLED);
        Long supplierId = bdc.getSupplierId();
        List<BusSupplierRate> list = selectBySupplierId(supplierId);
        Long drugsId = bdc.getDrugsId();
        if (FlymeUtils.isNotEmpty(drugsId)) {
            BusDrugs drugs = drugsService.getById(drugsId);
            bdc.setSupplierId(drugs.getSupplierId());
            list = selectByDrugsId(drugsId);
        }
        if (FlymeUtils.isEmpty(list)) {
            bdc.setEndDate(null);
        }
        extra.put("list", list);
        return ResultBody.ok();
    }

    @Override
    public ResultBody afterAdd(CriteriaSave cs, BusSupplierRate busDrugsConfig, EntityMap extra) {
        List<BusSupplierRate> list = extra.get("list");
        if (FlymeUtils.isNotEmpty(list)) {
            BusSupplierRate supplierRate = list.get(0);
            //计算旧配置截至日期
            supplierRate.setEndDate(DateUtils.plusDateDays(busDrugsConfig.getBeginDate(), -1));
            //禁用旧配置
            supplierRate.setConfigState(CommonConstants.DISABLED);
            saveOrUpdate(supplierRate);
        }
        return super.afterAdd(cs, busDrugsConfig, extra);
    }


    /**
     * 查询供应商全局费率配置
     *
     * @param supplierId
     * @return
     */
    private List<BusSupplierRate> selectBySupplierId(Long supplierId) {
        CriteriaQuery cq = new CriteriaQuery(BusSupplierRate.class);
        cq.eq(true, "supplierId", supplierId);
        cq.isNull("drugsId");
        cq.orderByDesc("beginDate");
        return list(cq);
    }

    /**
     * 查询供应商全局费率配置
     *
     * @param drugsId
     * @return
     */
    private List<BusSupplierRate> selectByDrugsId(Long drugsId) {
        CriteriaQuery cq = new CriteriaQuery(BusSupplierRate.class);
        cq.eq(true, "drugsId", drugsId);
        cq.isNotNull("supplierId");
        cq.orderByDesc("beginDate");
        return list(cq);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<BusSupplierRate> cq, BusSupplierRate bdc, EntityMap requestMap) {
        cq.select(BusSupplierRate.class, "*");
        cq.eq(BusSupplierRate.class, "supplierId");
        cq.eq(BusSupplierRate.class, "drugsId");
        cq.addSelect("r_formula.formulaContent r_formulaContent");
        cq.addSelect("h_formula.formulaContent h_formulaContent");
        cq.orderByDesc("bsr.beginDate");
        cq.createJoin(SysFormula.class).setJoinAlias("r_formula").setMainField("refundFormulaId");
        cq.createJoin(SysFormula.class).setJoinAlias("h_formula").setMainField("highTaxRateFormulaId");
        return ResultBody.ok();
    }

    @Override
    public BusSupplierRate findOrderSupplierRate(BusOrderDetails orderDetails, BusOrder busOrder) {
        Long supplierRateId = orderDetails.getSupplierRateId();
        if (FlymeUtils.isNotEmpty(supplierRateId)) {
            return getById(supplierRateId);
        }
        //供应商ID
        Long supplierId = orderDetails.getSupplierId();
        ApiAssert.isNotEmpty("供应商supplierId不能为空", supplierId);
        //药品ID
        Long drugsId = orderDetails.getDrugsId();
        //资信方式 1:全款 2:资信
        Integer delivery = busOrder.getDelivery();
        ApiAssert.isNotEmpty("资信方式delivery不能为空", delivery);
        //发货日期
        Date sendDate = busOrder.getSendDate();
        //回款日期
        Date takeDate = busOrder.getTakeDate();
        //查询条件使用的日期
        Date date = sendDate;
        if (delivery.equals(1)) {
            //全款使用回款日期,资信使用发货日期
            date = takeDate;
        }
        BusSupplierRate result = findByAllCondition(supplierId, drugsId, date);
        if (FlymeUtils.isEmpty(result)) {
            result = findBySupplierWithNullEndDate(supplierId, drugsId, date);
        }
        if (FlymeUtils.isEmpty(result)) {
            result = findBySupplierIdAndAllDate(supplierId, date);
        }
        if (FlymeUtils.isEmpty(result)) {
            result = findBySupplierIdWithNullEndDate(supplierId, date);
        }
        BigDecimal supplierTaxRate = orderDetails.getSupplierTaxRate();
        BigDecimal supplierSettleRate = orderDetails.getSupplierSettleRate();
        if (FlymeUtils.isNotEmpty(result)) {
            if (FlymeUtils.isNotEmpty(supplierTaxRate)) {
                result.setSupplierSettleRate(supplierSettleRate);
                result.setSupplierTaxRate(supplierTaxRate);
            }
        }else{
            BusOrderDetails  old = orderDetailsService.getById(orderDetails.getOrderDetailsId());
            if(FlymeUtils.isNotEmpty(old)){
                result=new BusSupplierRate();
                result.setSupplierTaxRate(old.getSupplierTaxRate());
                result.setSupplierSettleRate(old.getSupplierSettleRate());
            }
        }

        ApiAssert.isNotEmpty("供货方标准未配置", result);
        return result;
    }

    /**
     * 根据日期药品查询配置
     *
     * @param supplierId
     * @param drugsId
     * @param date
     * @return
     */
    private BusSupplierRate findByAllCondition(Long supplierId, Long drugsId, Date date) {
        CriteriaQuery cq = new CriteriaQuery(BusSupplierRate.class);
        cq.eq(true, "supplierId", supplierId);
        cq.eq(true, "drugsId", drugsId);
        cq.le(true, "beginDate", date);
        cq.ge(true, "endDate", date);
        cq.orderByDesc("beginDate");
        cq.last("limit 1");
        return getOne(cq);
    }

    /**
     * 根据日期(无结束日期)和药品查询配置
     *
     * @param supplierId
     * @param drugsId
     * @param date
     * @return
     */
    private BusSupplierRate findBySupplierWithNullEndDate(Long supplierId, Long drugsId, Date date) {
        CriteriaQuery cq = new CriteriaQuery(BusSupplierRate.class);
        cq.eq(true, "supplierId", supplierId);
        cq.eq(true, "drugsId", drugsId);
        cq.le(true, "beginDate", date);
        cq.last("limit 1");
        cq.orderByDesc("beginDate");
        return getOne(cq);
    }


    /**
     * 根据供应商按开始日期和截至日期查询
     *
     * @param supplierId
     * @param date
     * @return
     */
    private BusSupplierRate findBySupplierIdAndAllDate(Long supplierId, Date date) {
        CriteriaQuery cq = new CriteriaQuery(BusSupplierRate.class);
        cq.le(true, "beginDate", date);
        cq.ge(true, "endDate", date);
        cq.eq(true, "supplierId", supplierId);
        cq.orderByDesc("beginDate");
        cq.last("limit 1");
        return getOne(cq);
    }

    /**
     * 根据供应商按开始日期查询
     *
     * @param supplierId
     * @param date
     * @return
     */
    private BusSupplierRate findBySupplierIdWithNullEndDate(Long supplierId, Date date) {
        CriteriaQuery cq = new CriteriaQuery(BusSupplierRate.class);
        cq.eq(true, "supplierId", supplierId);
        cq.le(true, "beginDate", date);
        cq.orderByDesc("beginDate");
        cq.last("limit 1");
        return getOne(cq);
    }
}
